package instruments;

import collision.MainWindow;
import data.NavmeshRegion;
import data.FPoint;
import data.InstrumentGraphics;
import data.Triangle;
import java.awt.Cursor;
import pathfind.PolygonProcessor;

/**
 * @author Dmitry
 */
public class NewPolyCreateInstrument extends Instrument {
    private NavmeshRegion polygonArea;

    @Override
    public void initInstrument() {
        super.initInstrument();
        polygonArea = new NavmeshRegion();
        MainWindow.getInstance().getExtAreas().add(polygonArea);
    }

    private void addPointToTriangleQueue(int index) {
        if (polygonArea.getPointsQueue().contains(index)) {
            polygonArea.getPointsQueue().remove((Integer) index);
            return;
        }

        polygonArea.getPointsQueue().add(index);
        if (polygonArea.getPointsQueue().size() >= 3) {
            addTriangle();
            polygonArea.getPointsQueue().clear();
        }
    }

    private void addTriangle() {
        polygonArea.getTriangles().add(new Triangle(polygonArea.getPointsQueue().get(0), polygonArea.getPointsQueue().get(1), polygonArea.getPointsQueue().get(2)));
    }

    private void recalculateOutline() {
        polygonArea.getOutlines().clear();
        PolygonProcessor processor = new PolygonProcessor();
        polygonArea.setOutlines(processor.getPolygonOutline(polygonArea.getTriangles()));
        polygonArea.updateBoundaries();
    }

    private void addPoint(FPoint point) {
        for (int i = 0; i < polygonArea.getPoints().size(); i++) {
            if (polygonArea.getPoints().get(i) == null) {
                polygonArea.getPoints().set(i, point);
                return;
            }
        }

        polygonArea.getPoints().add(point);
    }

    private int getSelectedPointIndex(int x, int y) {
        for (int i = 0; i < polygonArea.getPoints().size(); i++) {
            FPoint point = polygonArea.getPoints().get(i);
            if (x >= point.getX() - NavmeshRegion.POINT_RADIUS && x <= point.getX() + NavmeshRegion.POINT_RADIUS
                    && y >= point.getY() - NavmeshRegion.POINT_RADIUS && y <= point.getY() + NavmeshRegion.POINT_RADIUS) {
                return i;
            }
        }

        return -1;
    }

    @Override
    public void mouseDown(int x, int y, int modifiers) {
        super.mouseDown(x, y, modifiers);
        int selectedIndex = getSelectedPointIndex(x, y);
        if (selectedIndex == -1 && isLeftDown(modifiers)) {
            addPoint(new FPoint(x, y));
        }

        if (selectedIndex != -1 && isRightDown(modifiers)) {
            addPointToTriangleQueue(selectedIndex);
            recalculateOutline();
        }

        redraw();
    }

    @Override
    public void mouseMove(int x, int y, int oldX, int oldY) {
        MainWindow.getInstance().setTitle("X=" + x + "  Y=" + y);
        super.mouseMove(x, y, oldX, oldY);
        if (getSelectedPointIndex(x, y) != -1) {
            MainWindow.getInstance().getDrawField().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
        } else {
            MainWindow.getInstance().getDrawField().setCursor(Cursor.getDefaultCursor());
        }
    }

    @Override
    public void onDraw(InstrumentGraphics g) {
        super.onDraw(g);
        for (NavmeshRegion area : MainWindow.getInstance().getExtAreas()) {
            area.draw(g);
        }
    }
}
